package com.stephen.data.linkedlist;

/**
 * @author: stephen
 * @create: 2020-01-30 16:33
 * @description: 双向链表,add,addByOrder(这个比较不一样),del,list
 *
 */
public class DoubleLinkedListDemo {
    public static void main(String[] args) {
        HeroNode2 h1 = new HeroNode2(1, "a", "aa");
        HeroNode2 h2 = new HeroNode2(2, "b", "bb");
        HeroNode2 h3 = new HeroNode2(3, "c", "cc");
        HeroNode2 h4 = new HeroNode2(4, "d", "dd");
        DoubleLinkedListDemo doubleList = new DoubleLinkedListDemo();
        doubleList.addByOrder(h1);
        doubleList.addByOrder(h3);
        doubleList.addByOrder(h2);
        doubleList.addByOrder(h4);
        doubleList.list();
        // System.out.println("修改双向链表--");
        // HeroNode2 newNode = new HeroNode2(3, "cupdate", "cccc");
        // doubleList.update(newNode);
        // doubleList.list();
        // System.out.println("删除双向链表");
        // // doubleList.del(3);
        // doubleList.list();


    }

    private HeroNode2 head = new HeroNode2(0,"","");

    public HeroNode2 getHead() {
        return head;
    }


    /**
     * 双向链表的删除
     * 1.可以直接找到要删除的节点
     * 2.找到后,自我删除即可
     * @param no
     */
    public void del(int no) {
        if (head.next == null) {
            System.out.println("链表为空,无法删除");
            return;
        }
        HeroNode2 temp = head.next;
        boolean isFind = false; // 是否找到
        while (temp != null) {
            if (temp.no == no) {
                isFind = true;
                break;
            }
            temp = temp.next;
        }
        if (isFind) {
            // 找到后,可以修改
            temp.pre.next = temp.next;
            // 如果要删除的节点是最后一个节点,则temp.next = null
            // 会出现空指针异常???
            if (temp.next != null) {
                temp.next.pre = temp.pre;
            }
        } else {
            System.out.printf("没有找到编号为[%d]的节点\n",no);
        }

    }

    /**
     * 双向链表的修改,与单链表相同
     * @param newNode
     */
    public void update(HeroNode2 newNode) {
        if (head.next == null) {
            System.out.println("空链表,无法修改---");
            return;
        }
        HeroNode2 temp = head.next;
        boolean ifFind = false; // 是否找到
        while (temp != null) {
            if (temp.no == newNode.no) {
                ifFind = true;
                break;
            }
            temp = temp.next;
        }

        if (ifFind) {
            temp.name = newNode.name;
            temp.nickName = newNode.nickName;
        } else {
            System.out.printf("没有找到编号为[%d]的结点",temp.no);
        }

    }

    /**
     * 双向链表的添加,与单链表不同
     */
    public void add(HeroNode2 newNode) {
        HeroNode2 temp = head;
        // 遍历双向链表,找到最后
        while (temp.next != null) {
            temp = temp.next;
        }
        // 此时链表的最后一个结点为temp
        // 插入新结点
        temp.next = newNode;
        newNode.pre = temp;
    }

    /**
     * 双向链表按编号顺序添加
     * @param newNode
     */
    public void addByOrder(HeroNode2 newNode) {
        HeroNode2 temp = head;
        boolean flag = false;
        while (temp.next != null) {
            if (temp.next.no > newNode.no) {
                // 找到可以添加的位置,跳出循环
                break;
            } else if (temp.next.no == newNode.no) {
                flag = true;
                System.out.printf("编号[%d]已经存在,不能再添加",newNode.no);
                break;
            }
            temp = temp.next;
        }
        if (!flag) {
            HeroNode2 next = temp.next;
            temp.next = newNode;
            newNode.pre = temp;
            // 如果不是添加到最后,还需要与之前的next节点建立联系
            if (next != null) {
                newNode.next = next;
                next.pre = newNode;
            }
        } else {
            System.out.printf("没有找到编号为[%d]的节点\n",newNode.no);
        }

    }

    /**
     * 双向链表遍历,与单链表相同
     */
    public void list() {
        if (head.next == null) {
            return;
        }
        HeroNode2 cur = head.next;
        while (cur != null) {
            System.out.println(cur);
            cur = cur.next;
        }
    }



}

// 基础节点
class HeroNode2 {
    public int no;
    public String name;
    public String nickName;
    public HeroNode2 pre; // 前一个结点
    public HeroNode2 next; // 后一个结点

    public HeroNode2(int no, String name, String nickName) {
        this.no = no;
        this.name = name;
        this.nickName = nickName;
    }

    @Override
    public String toString() {
        return "HeroNode{" +
                "no=" + no +
                ", name='" + name + '\'' +
                ", nickName='" + nickName +
                '}';
    }
}